//***************************************************************************
//*
//*	File:			dswl_documents.cpp
//*	Description:	Wrapper for IDocuments interface
//*
//***************************************************************************

//
//--------------------------------------------------------------- PRECOMPILED
//

#include "stdafx.h"

//
//--------------------------------------------------- DECLARATION DEPENDENCIES
//

//
//--------------------------------------------------------------- DECLARATION
//

#include "../Inc/dswl_documents.h"

//
//--------------------------------------------------- DEFINITION DEPENDENCIES
//

//
//-------------------------------------------------------------- PREPROCESSOR
//

#ifdef	_DEBUG
#define new DEBUG_NEW
#undef	THIS_FILE
static	char THIS_FILE[] = __FILE__;
#endif

//
//---------------------------------------------------------------- DEFINITION
//

/*
static void g_TestCasts()
{
	// test _safe_ conversions
	IDocuments* pITest;
	CIDocuments test	 ( pITest );
	CIDocuments test2 = pITest ;

	test = test2;
	test = pITest;

	#ifdef _DSWL_SWITCH_USE_AUTOCAST

	// test _critical_ conversions
	pITest = test;
	CComPtr< IDocuments > tmplTest = test;

	#endif
}
*/

//
//---------------------------------------------------------------------------------------------------
//*************************************     CON/DESTRUCTION     *************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																					  Constructor
//***************************************************************************************************
//**	@DOC		CONSTRUCTION
//**	@MFUNC		Default constructor
//**	@PARM		[in] A pointer to the interface to attach to
//**	@END
//***************************************************************************************************
//inline
CIDocuments::CIDocuments( IDocuments* a_pIDocuments /*= NULL*/ )
{
	this->m_pIDocuments = a_pIDocuments;
}

//***************************************************************************************************
//**																					   Destructor
//***************************************************************************************************
//**	@DOC		CONSTRUCTION
//**	@MFUNC		Default destructor
//**	@END
//***************************************************************************************************
//inline
CIDocuments::~CIDocuments()
{
	this->m_pIDocuments = NULL;	// explicitly release the interface now
}

//
//---------------------------------------------------------------------------------------------------
//***************************************     PROPERTIES     ****************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																				   GetApplication
//***************************************************************************************************
//**	@DOC		PROPERTIES
//**	@MFUNC		Returns the application these documents belong to
//**	@RDESC		A pointer to the application's interface
//**	@END
//***************************************************************************************************
//inline
CIApplication CIDocuments::GetApplication( void ) const 
{
	//
	//	CHECK VALIDITY
	//
	if ( FALSE == this->IsValid() )
	{
		return NULL;
	}

	//
	//	DELEGATE
	//
	IDispatch* pIDispatch = NULL;

	DSWL_VERIFY( this->m_pIDocuments->get_Application( &pIDispatch ) );

	//
	//	QUERY INTERFACE
	//
	CComQIPtr< IApplication, &IID_IApplication > pIApplication ( pIDispatch );	

	//
	//	REPELASE DISPATCH INTERFACE
	//
	DSWL_RELEASE_EX( pIDispatch, CIDocuments::GetApplication );

	//
	//	RETURN QUERIED INTERFACE
	//
	return pIApplication.p;												
}

//***************************************************************************************************
//**																						 GetCount 
//***************************************************************************************************
//**	@DOC		PROPERTIES
//**	@MFUNC		Returns the number of documents in this collection
//**	@RDESC		The number of documents in this collection
//**	@END
//***************************************************************************************************
//inline
long CIDocuments::GetCount( void ) const 
{
	//
	//	CHECK VALIDITY
	//
	if ( FALSE == this->IsValid() )
	{
		return 0l;
	}

	//
	//	DELEGATE
	//
	long lCount = 0;

	DSWL_VERIFY( this->m_pIDocuments->get_Count( &lCount ) );

	return lCount;
}

//
//---------------------------------------------------------------------------------------------------
//***************************************     INFORMATION     ***************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																						   IsNull
//***************************************************************************************************
//**	@DOC		INFORMATION
//**	@MFUNC		Determines whether the internal pointer is <t NULL>
//**	@RDESC		<t TRUE> if the internal pointer is <t NULL>, <t FALSE> otherwise.
//**	@END
//***************************************************************************************************
//inline
BOOL CIDocuments::IsNull( void ) const
{
	return ( NULL == this->m_pIDocuments.p );
}

//***************************************************************************************************
//**																						  IsValid
//***************************************************************************************************
//**	@DOC		INFORMATION
//**	@MFUNC		Determines whether the internal pointer differs from <t NULL>
//**	@RDESC		<t TRUE> if the internal pointer differs from <t NULL>, <t FALSE> otherwise.
//**	@END
//***************************************************************************************************
//inline
BOOL CIDocuments::IsValid( void ) const
{
	return ( NULL != this->m_pIDocuments.p );
}

//
//---------------------------------------------------------------------------------------------------
//***********************************     ELEMENT MANAGEMENT     ************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																					   		GetAt
//***************************************************************************************************
//**	@DOC		ELEMENT MANAGEMENT
//**	@MFUNC		Determines the item at specified 0-based index. 
//**	@PARM		[in] The 0-based index of the item to return
//**	@RDESC		A pointer to the document's generic interface
//**	@END
//***************************************************************************************************
//inline
CIGenericDocument CIDocuments::GetAt( long a_lIndex ) const 
{
	ASSERT( TRUE == this->IsValid() );

	return this->GetItem( a_lIndex + 1 );
}

//***************************************************************************************************
//**																					   	  GetItem
//***************************************************************************************************
//**	@DOC		ELEMENT MANAGEMENT
//**	@MFUNC		Determines the item at specified 1-based index. 
//**	@PARM		[in] The 1-based index of the item to return
//**	@RDESC		A pointer to the document's generic interface
//**	@END
//***************************************************************************************************
//inline
CIGenericDocument CIDocuments::GetItem( long a_lItem ) const 
{
	ASSERT( TRUE == this->IsValid() );

	//
	//	GET ITEM'S DISPATCH INTERFACE
	//
	IDispatch*	pIDispatch = NULL;
	CComVariant	varCount( a_lItem );

	DSWL_VERIFY( this->m_pIDocuments->Item( varCount, &pIDispatch ) );

	//
	//	QUERY INTERFACE
	//
	CComQIPtr< IGenericDocument, &IID_IGenericDocument > pIGenericDocument ( pIDispatch );	

	//
	//	REPELASE DISPATCH INTERFACE
	//
	DSWL_RELEASE_EX( pIDispatch, CIDocuments::GetItem );

	//
	//	RETURN QUERIED INTERFACE
	//
	return pIGenericDocument.p;												
}

//***************************************************************************************************
//**																					   		  Add
//***************************************************************************************************
//**	@DOC		ELEMENT MANAGEMENT
//**	@MFUNC		Inserts a new document to the container
//**	@PARM		[in] The document type
//**	@RDESC		A pointer to the document's generic interface
//**	@END
//***************************************************************************************************
//inline
CIGenericDocument CIDocuments::Add( const CString& a_strDocumentType ) 
{
	ASSERT( TRUE == this->IsValid() );

	//
	//	GET ITEM'S DISPATCH INTERFACE
	//
	IDispatch*	pIDispatch	= NULL;
	CComBSTR	bszType		( a_strDocumentType );
	CComVariant	varReserved	( 0l );

	DSWL_VERIFY( this->m_pIDocuments->Add( bszType, varReserved, &pIDispatch ) );

	//
	//	QUERY INTERFACE
	//
	CComQIPtr< IGenericDocument, &IID_IGenericDocument > pIGenericDocument ( pIDispatch );	

	//
	//	REPELASE DISPATCH INTERFACE
	//
	DSWL_RELEASE_EX( pIDispatch, CIDocuments::Add );

	//
	//	RETURN QUERIED INTERFACE
	//
	return pIGenericDocument.p;												
}

//***************************************************************************************************
//**																					   		 Open
//***************************************************************************************************
//**	@DOC		ELEMENT MANAGEMENT
//**	@MFUNC		Inserts an existing document to the container
//**	@PARM		[in] The path to the document
//**	@PARM		[in] The opening mode
//**	@PARM		[in] A flag indicating whether to open the file in read-only mode
//**	@RDESC		A pointer to the document's generic interface
//**	@END
//***************************************************************************************************
//inline
CIGenericDocument CIDocuments::Open( const CString& a_strFileName, const CString& a_strOpenAs, BOOL a_bReadOnly ) 
{
	ASSERT( TRUE == this->IsValid() );

	//
	//	DELEGATE
	//
	IDispatch*	pIDispatch	= NULL;
	CComBSTR	bszFileName	( a_strFileName );
	CComBSTR	bszType		( a_strOpenAs	);
	CComVariant	varType		( bszType		);
	CComVariant	varReadOnly	( a_bReadOnly	);
	CComVariant	varReserved	( 0l );

	/*DSWL_VERIFY(*/ this->m_pIDocuments->Open( bszFileName, varType, varReadOnly, &pIDispatch ) /*)*/;

	//
	//	QUERY INTERFACE
	//
	CComQIPtr< IGenericDocument, &IID_IGenericDocument > pIGenericDocument ( pIDispatch );	

	//
	//	REPELASE DISPATCH INTERFACE
	//
	DSWL_RELEASE_EX( pIDispatch, CIDocuments::Open );

	//
	//	RETURN QUERIED INTERFACE
	//
	return pIGenericDocument.p;												
}

//***************************************************************************************************
//**																					   	  SaveAll
//***************************************************************************************************
//**	@DOC		ELEMENT MANAGEMENT
//**	@MFUNC		Saves all documents
//**	@PARM		[in] A flag indicating whether to prompt for confirmation
//**	@RDESC		A pointer to the document's generic interface
//**	@END
//***************************************************************************************************
//inline
DsSaveStatus CIDocuments::SaveAll( BOOL a_bPrompt ) 
{
	ASSERT( TRUE == this->IsValid() );

	DsSaveStatus	enuResult	;
	CComVariant		varPrompt	( a_bPrompt	);

	DSWL_VERIFY( this->m_pIDocuments->SaveAll( varPrompt, &enuResult ) );

	return enuResult;
}

//***************************************************************************************************
//**																					   	 CloseAll
//***************************************************************************************************
//**	@DOC		ELEMENT MANAGEMENT
//**	@MFUNC		Closes all documents
//**	@PARM		[in] A flag indicating whether to save changes
//**	@RDESC		A pointer to the document's generic interface
//**	@END
//***************************************************************************************************
//inline
DsSaveStatus CIDocuments::CloseAll( BOOL a_bSaveChanges ) 
{
	ASSERT( TRUE == this->IsValid() );

	DsSaveStatus	enuResult	;
	CComVariant		varSave		( a_bSaveChanges );

	DSWL_VERIFY( this->m_pIDocuments->CloseAll( varSave, &enuResult ) );

	return enuResult;
}

//
//---------------------------------------------------------------------------------------------------
//***************************************     EXTENSIONS     ****************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																				   FindByFullName
//***************************************************************************************************
//**	@DOC		EXTENSIONS
//**	@MFUNC		Find the document with the specified full name
//**	@PARM		[in] The full name of the document to find
//**	@RDESC		A pointer to the document's generic interface
//**	@END
//***************************************************************************************************
//inline
CIGenericDocument CIDocuments::FindByFullName( const CString& a_strFullName ) const
{
	ASSERT( TRUE == this->IsValid() );

	//
	//	ENUMERATE DOCUMENTS
	//
	for ( int iDocument = 0; iDocument < this->GetCount(); iDocument++ )
	{
		//
		//	GET DOCUMENT
		//
		CIGenericDocument pIGenericDocument = this->GetAt( iDocument );
	
		//
		//	COMPARE FULL NAME
		//
		if ( a_strFullName == pIGenericDocument.GetFullName() )
		{
			//
			//	RETURN MATCHING DOCUMENT
			//
			return pIGenericDocument;
		}
	}

	//
	//	NO MATCH
	//
	return NULL;
}

//
//---------------------------------------------------------------------------------------------------
//****************************************     OPERATORS     ****************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																					  operator ==
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Comparison operator
//**	@PARM		[in] The text document to compare to
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
bool CIDocuments::operator == ( const CIDocuments& a_Other ) const 
{
	return this->m_pIDocuments == a_Other.m_pIDocuments;
}

//***************************************************************************************************
//**																					  operator !=
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Comparison operator
//**	@PARM		[in] The text document to compare to
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
bool CIDocuments::operator != ( const CIDocuments& a_Other ) const 
{
	return this->m_pIDocuments != a_Other.m_pIDocuments;
}

//***************************************************************************************************
//**																					  operator <=
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Comparison operator
//**	@PARM		[in] The text document to compare to
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
bool CIDocuments::operator <= ( const CIDocuments& a_Other ) const 
{
	return this->m_pIDocuments.p <= a_Other.m_pIDocuments.p;
}

//***************************************************************************************************
//**																					  operator >=
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Comparison operator
//**	@PARM		[in] The text document to compare to
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
bool CIDocuments::operator >= ( const CIDocuments& a_Other ) const 
{
	return this->m_pIDocuments.p >= a_Other.m_pIDocuments.p;
}

//***************************************************************************************************
//**																					   operator <
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Comparison operator
//**	@PARM		[in] The text document to compare to
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
bool CIDocuments::operator < ( const CIDocuments& a_Other ) const 
{
	return this->m_pIDocuments.p < a_Other.m_pIDocuments.p;
}

//***************************************************************************************************
//**																					   operator >
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Comparison operator
//**	@PARM		[in] The text document to compare to
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
bool CIDocuments::operator > ( const CIDocuments& a_Other ) const 
{
	return this->m_pIDocuments.p > a_Other.m_pIDocuments.p;
}

//***************************************************************************************************
//**																					   operator =
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Copy operator
//**	@PARM		[in] The text document to attach to
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
CIDocuments& CIDocuments::operator = ( IDocuments* a_pIOther ) 
{
	this->m_pIDocuments = a_pIOther;

	return (*this);
}

//***************************************************************************************************
//**																					   operator *
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Dereference operator
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
IDocuments* CIDocuments::operator * ( void ) 
{
	return this->m_pIDocuments.p;
}

//***************************************************************************************************
//**																				 const operator *
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Dereference operator
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
const IDocuments* CIDocuments::operator * ( void ) const 
{
	return this->m_pIDocuments.p;
}

//***************************************************************************************************
//**																					  operator ->
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Member access operator
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
IDocuments* CIDocuments::operator -> ( void ) 
{
	return * (*this);
}

//***************************************************************************************************
//**																				const operator ->
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Member access operator
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
const IDocuments* CIDocuments::operator -> ( void ) const 
{
	return * (*this);
}

//***************************************************************************************************
//**																				const operator []
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Subscription operator
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
CIGenericDocument CIDocuments::operator [] ( int a_iIndex ) const 
{
	return this->GetAt( a_iIndex );
}

//---------------------------------------------------------------------------------------------------
//***************************************************************************************************
//---------------------------------------------------------------------------------------------------

#ifdef _DSWL_SWITCH_USE_AUTOCAST
#ifdef _DSWL_SWITCH_USE_UNSAFE_AUTOCAST

//***************************************************************************************************
//**																				 const operator *
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		TypeCast operator
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
CIDocuments::operator IDocuments* ( void ) const 
{
	return this->m_pIDocuments.p;
}

#else

//***************************************************************************************************
//**																					   operator *
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		TypeCast operator
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
CIDocuments::operator IDocuments* ( void ) 
{
	return this->m_pIDocuments.p;
}

//***************************************************************************************************
//**																				 const operator *
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		TypeCast operator
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
CIDocuments::operator const IDocuments* ( void ) const 
{
	return this->m_pIDocuments.p;
}

#endif
#endif


